import {
  Cartesian3,
  Math as CesiumMath,
  Ellipsoid,
  Cartographic,
  EllipsoidTerrainProvider,
  Cesium3DTileFeature,
  Cesium3DTileset,
  Model,
  EllipsoidGeodesic,
  defined,
  Entity,
  ScreenSpaceEventHandler,
  ScreenSpaceEventType,
  CustomDataSource,
  HorizontalOrigin,
  VerticalOrigin,
  Cartesian2, CallbackProperty, PolygonHierarchy, Color, JulianDate
} from "cesium";

export default class CesiumDraw {

  /**
   *
   * @param options.clampToGround  是否开启贴地功能，当设置了地图的地形并clampToGround==true时，图形会贴地
   * @param options.measure 是否开启测绘功能
   * @param options.basePath 路径
   */
  constructor(options) {
    this.clampToGround = options.clampToGround || false
    this.measure = options.measure || true
    this.basePath = options.basePath || ''
    this.drawLayer = CustomDataSource('measureLayer')
    window.viewer.dataSources.add(this.drawLayer)
  }


  /**
   * 坐标转换 84 转换笛卡尔
   * @param {Object} position { longitude, latitude, height}
   * @returns {Cartesian3}
   */
  transformWGS84ToCartesian(position) {
    if (window.viewer) {
      return position ? Cartesian3.fromDegrees(
         position.longitude,position.latitude,position.height
      ) : Cartesian3.ZERO
    }
  }

  /**
   * 坐标数组转换 84转换笛卡尔
   * @param WSG84Arr
   * @returns {*|*[]}
   */
  transformWGS84ArrayToCartesianArray(WSG84Arr) {
    if (window.viewer && WSG84Arr) {
      return WSG84Arr ? WSG84Arr.map(position => this.transformWGS84ToCartesian(position)) : []
    }
  }

  /**
   *
   * @param {Object} cartesian Cartesian3三维坐标系
   * @returns {{latitude: number, longitude: number, height: number}}
   */
  transformCartesianToWGS84(cartesian) {
    if (window.viewer && cartesian) {
      // 初始化为 WGS84 标准的椭球体实例。
      const ellipsoid = Ellipsoid.WGS84
      const cartographic = ellipsoid.cartesianToCartographic(cartesian)
      return {
        longitude: CesiumMath.toDegrees(cartographic.longitude),
        latitude: CesiumMath.toDegrees(cartographic.latitude),
        height: cartographic.height
      }
    }
  }


  /***
   * 坐标数组转换 笛卡尔转84
   *
   * @param {Array} cartesianArr 三维位置坐标数组
   *
   * @return {Array} {lng,lat,alt} 地理坐标数组
   */
  transformCartesianArrayToWGS84Array(cartesianArr) {
    if (window.viewer && cartesianArr) {
      return cartesianArr ? cartesianArr.map(cartesian => this.transformCartesianToWGS84(cartesian)) : []
    }
  }

  /**
   * 84坐标转弧度坐标
   * @param {Object} position wgs84
   * @return {Object} Cartographic 弧度坐标
   *
   */
  transformWGS84ToCartographic(position) {
    return position ? Cartographic.fromDegrees(position.longitude, position.latitude, position.height) : Cartographic.ZERO
  }


  /**
   * 拾取位置点
   * @param px 屏幕坐标
   * @return {Object} Cartographic 弧度坐标
   */
  getCatesian3FromPX(px) {
    if (window.viewer && px) {
      // 返回位于的所有基元的对象列表
      const picks = window.viewer.scene.drillPick(px)
      let cartesian = null
      let isOn3dtiles = false,
          isOnTerrain = false
      for (let i in picks) {
        let pick = picks[i]

        if (
            (pick && pick.primitive instanceof Cesium3DTileFeature) ||
            (pick && pick.primitive instanceof Cesium3DTileset) ||
            (pick && pick.primitive instanceof Model)
        ) {
          //模型上拾取
          isOn3dtiles = true
        }
        // 3dtilset
        if (isOn3dtiles) {
          window.viewer.scene.pick(px) // pick
          cartesian = window.viewer.scene.pickPosition(px)
          if (cartesian) {
            let cartographic = Cartographic.fromCartesian(cartesian)
            if (cartographic.height < 0) cartographic.height = 0
            let lon = CesiumMath.toDegrees(cartographic.longitude),
                lat = CesiumMath.toDegrees(cartographic.latitude),
                height = cartographic.height
            cartesian = this.transformWGS84ToCartesian({ lng: lon, lat: lat, alt: height })
          }
        }
      }
      // 地形
      let boolTerrain = window.viewer.terrainProvider instanceof EllipsoidTerrainProvider
      // Terrain
      if (!isOn3dtiles && !boolTerrain) {
        const ray = window.viewer.scene.camera.getPickRay(px)
        if (!ray) return null
        // 找到光线与渲染过的地球表面之间的交点。射线必须用世界坐标来表示。
        cartesian = window.viewer.scene.globe.pick(ray, window.viewer.scene)
        isOnTerrain = true
      }
      // 地球
      if (!isOn3dtiles && !isOnTerrain && boolTerrain) {
        cartesian = window.viewer.scene.camera.pickEllipsoid(px, window.viewer.scene.globe.ellipsoid)
      }
      if (cartesian) {
        let position = this.transformCartesianToWGS84(cartesian)
        if (position.height < 0) {
          cartesian = this.transformWGS84ToCartesian(position, 0.1)
        }
        return cartesian
      }
      return false
    }
  }

  /**
   * 获取84坐标的距离
   * @param positions
   * @returns {*} positions
   */
  getPositionDistance(positions) {
    let distance = 0
    for (let i = 0; i < positions.length - 1; i++) {
      let point1cartographic = this.transformWGS84ToCartographic(positions[i])
      let point2cartographic = this.transformWGS84ToCartographic(positions[i + 1])
      let geodesic = new EllipsoidGeodesic()
      geodesic.setEndPoints(point1cartographic, point2cartographic)
      let s = geodesic.surfaceDistance
      s = Math.sqrt(Math.pow(s, 2) + Math.pow(point2cartographic.height - point1cartographic.height, 2))
      distance = distance + s
    }
    return distance.toFixed(3)
  }

  /**
   * 计算一组坐标组成多边形的面积
   * @param positions
   * @returns {number}
   */
  getPositionsArea(positions) {
    let result = 0
    if (positions) {
      let h = 0
      let ellipsoid = Ellipsoid.WGS84
      positions.push(positions[0])
      for (let i = 1; i < positions.length; i++) {
        let oel = ellipsoid.cartographicToCartesian(this.transformWGS84ToCartographic(positions[i - 1]))
        let el = ellipsoid.cartographicToCartesian(this.transformWGS84ToCartographic(positions[i]))
        h += oel.x * el.y - el.x * oel.y
      }
      result = Math.abs(h).toFixed(2)
    }
    return result
  }


  /**
   * 计算一组坐标中心点
   * @param cartesianPositions
   * @returns {module:cesium.Cartesian3|undefined}
   */
  computePolygonCenter(cartesianPositions) {
    if (!defined(cartesianPositions) || cartesianPositions.length === 0) {
      return undefined; // 无效输入
    }
    console.log(cartesianPositions, "cartesianPositions");
    let lonArr = []
    let latArr = []
    cartesianPositions.map((item) => {
      lonArr.push(item.x)
      latArr.push(item.y)
    })
    let maxLon = Math.max.apply(Math, lonArr);
    let minLon = Math.min.apply(Math, lonArr);
    let maxLat = Math.max.apply(Math, latArr);
    let minLat = Math.min.apply(Math, latArr);
    let lonCenter = ((maxLon - minLon) / 2) + minLon;
    let latCenter = ((maxLat - minLat) / 2) + minLat;
    console.log(lonCenter, latCenter, "latCenter");
    // 计算所有顶点的平均坐标
    let center = new Cartesian3();
    for (const position of cartesianPositions) {
      Cartesian3.add(center, position, center);
    }
    Cartesian3.divideByScalar(center, cartesianPositions.length, center);
    center.x = lonCenter
    center.y = latCenter
    return center;
  }


  /**
   * 测距
   * @param options
   */
  drawLineMeasureGraphics(options = {}) {
    const { clampToGround, measure, style } = options
    if (window.viewer && options) {
      let positions = [],
          lineEntity = new Entity(),
          lineObj,
          distance = 0,
          labelEntityOne = null
          const handlers = new ScreenSpaceEventHandler(window.scene.canvas)

      // 左键点击
      handlers.setInputAction((movement) => {
        const cartesian = this.getCatesian3FromPX(movement.position)
        if (cartesian && cartesian.x) {
          if (positions.length === 0) {
            positions.push(cartesian.clone())
          }
          // 添加量测信息点
          if (style?.point) {
            addInfoPoint(cartesian)
          }
          positions.push(cartesian)
        }
      }, ScreenSpaceEventType.LEFT_CLICK)

      // 移动时
      handlers.setInputAction((movement) => {
        const cartesian = this.getCatesian3FromPX(movement.endPosition)
        //鼠标提示信息
        if (labelEntityOne) {
          this.drawLayer.entities.remove(labelEntityOne)
          labelEntityOne = null
        }
        labelEntityOne = new Entity()
        labelEntityOne.position = cartesian
        labelEntityOne.label = {
          text: positions.length > 0 ? '右击结束绘制' : '单击打开始绘制',
          show: true,
          showBackground: true,
          font: '14px monospace',
          horizontalOrigin: HorizontalOrigin.LEFT,
          verticalOrigin: VerticalOrigin.BOTTOM,
          pixelOffset: new Cartesian2(-20, -80) //left top
        }
        labelEntityOne = this.drawLayer.entities.add(labelEntityOne)
        if (positions.length >= 2) {
          if (cartesian && cartesian.x) {
            positions.pop()
            positions.push(cartesian)
          }
        }
      }, ScreenSpaceEventType.MOUSE_MOVE)

      // 鼠标右键
      handlers.setInputAction((movement) => {
        handlers.destroy()
        if (labelEntityOne) this.drawLayer.entities.remove(labelEntityOne)
        const cartesian = this.getCatesian3FromPX(movement.position)
        addInfoPoint(cartesian)
        if (typeof options.callback === 'function') {
          options.callback({
            points: this.transformCartesianArrayToWGS84Array(positions),
            entity: lineObj,
            measure: Number(distance)
          })}
        }, ScreenSpaceEventType.RIGHT_CLICK)


      // 面集合
      lineEntity.polyline = {
        width: style?.line?.width || 1,
        material: style?.line?.material || BLUE.withAlpha(0.8),
        clampToGround: clampToGround || false
      }
      lineEntity.polyline.positions = new CallbackProperty(function () {
        return positions
      }, false)
      lineObj = this.drawLayer.entities.add(lineEntity)
      const addInfoPoint = (position) => {
        const labelEntity = new Entity()
        labelEntity.position = position
        labelEntity.point = {
          pixelSize: style?.point?.pixelSize || 10,
          outlineColor: style?.point?.outlineColor || Color.BLUE,
          outlineWidth: style?.point?.outlineWidth || 0,
          color: style?.point?.color || Color.WHITE,
          show: true
        }
        if (measure) {
          distance = this.getPositionDistance(this.transformCartesianArrayToWGS84Array(positions))

          labelEntity.label = {
            text:
                (distance / 1000).toFixed(4) +
                '公里',
            show: true,
            showBackground: true,
            font: '14px monospace',
            horizontalOrigin: HorizontalOrigin.LEFT,
            verticalOrigin: VerticalOrigin.BOTTOM,
            pixelOffset: new Cartesian2(-20, -80) //left top
          }
        }

        this.drawLayer.entities.add(labelEntity)
      }
    }

  }

  /**
   * 测面
   * @param options
   */
  drawAreaMeasureGraphics(options = {}) {
    const { clampToGround, measure, style } = options
    if (window.viewer && options) {
      let positions = [],
          polygon = new PolygonHierarchy(),
          polygonEntity = new Entity(),
          polyObj = null,
          area = 0,
          label = '',
          labelEntityOne
      const handlers = new ScreenSpaceEventHandler(window.scene.canvas)
      //左键点击
      handlers.setInputAction((movement) => {
        const cartesian = this.getCatesian3FromPX(movement.position)
        if (style?.point) {
          addInfoPoint(cartesian)
        }

        if (cartesian && cartesian.x) {
          if (positions.length === 0) {
            polygon.positions.push(cartesian.clone())
            positions.push(cartesian.clone())
          }
          positions.push(cartesian.clone())
          polygon.positions.push(cartesian.clone())

          if (!polyObj) create()
        }

      }, ScreenSpaceEventType.LEFT_CLICK)

      // 鼠标移动
      handlers.setInputAction((movement) => {
        const cartesian = this.getCatesian3FromPX(movement.endPosition)
        // var cartesian = $this._viewer.scene.camera.pickEllipsoid(movement.endPosition, $this._viewer.scene.globe.ellipsoid);

        //鼠标提示信息
        if (labelEntityOne) this.drawLayer.entities.remove(labelEntityOne)
        labelEntityOne.position = cartesian
        labelEntityOne.label = {
          text: positions.length > 0 ? '右击结束绘制' : '单击打开始绘制',
          show: true,
          showBackground: true,
          font: '14px monospace',
          horizontalOrigin: HorizontalOrigin.LEFT,
          verticalOrigin: VerticalOrigin.BOTTOM,
          pixelOffset: new Cartesian2(-20, -80) //left top
        }
        this.drawLayer.entities.add(labelEntityOne)
        if (positions.length >= 2) {
          if (cartesian && cartesian.x) {
            positions.pop()
            positions.push(cartesian)
            polygon.positions.pop()
            polygon.positions.push(cartesian)
          }
        }
      }, ScreenSpaceEventType.MOUSE_MOVE)


      // 鼠标右键
      handlers.setInputAction((movement) => {
        if (labelEntityOne) this.drawLayer.entities.remove(labelEntityOne)
        handlers.destroy()
        positions.push(positions[0])
        let lastPoint = positions[positions.length - 2]
        if (style?.centerPoint && measure) {
          let center = this.computePolygonCenter(positions)

          // 添加信息点
          if (center) _addInfoPoint(center)
          if (style?.point) {
            addInfoPoint(lastPoint)
          }
        } else {
          addInfoPoint(lastPoint)
        }
        if (typeof options.callback === 'function') {
          options.callback({
            points: this.transformCartesianArrayToWGS84Array(positions),
            entity: polyObj,
            measure: Number(area)
          })
          // options.callback($this.transformCartesianArrayToWGS84Array(positions), polyObj)
        }
      }, ScreenSpaceEventType.RIGHT_CLICK)

      // 添加信息点
      const _addInfoPoint = (position) => {
        const labelEntity = new Entity()
        labelEntity.position = position
        labelEntity.point = {
          pixelSize: style?.centerPoint?.pixelSize || style?.point?.pixelSize || 10,
          outlineColor: style?.centerPoint?.outlineColor || style?.point?.outlineColor || Color.BLUE,
          outlineWidth: style?.centerPoint?.outlineWidth || style?.point?.outlineWidth || 0,
          color: style?.centerPoint?.color || style?.point?.color || Color.WHITE
        }
        if (measure) {
          area = this.getPositionsArea(this.transformCartesianArrayToWGS84Array(positions))
          // 获取原始位置
          const originalPosition = labelEntity.position.getValue(JulianDate.now())
          // 向上偏移100米
          const newHeight = 10 // 向上偏移100米
          const newPosition = new Cartesian3(originalPosition.x, originalPosition.y, originalPosition.z + newHeight)
          // 更新实例属性
          labelEntity.position.setValue(newPosition);
          labelEntity.label = {
            text:
                (area / 1000000.0).toFixed(4) +
                '平方公里',
            show: true,
            showBackground: true,
            font: '14px monospace',
            horizontalOrigin: HorizontalOrigin.LEFT,
            verticalOrigin: VerticalOrigin.BOTTOM,
            pixelOffset: new Cartesian2(-55, -10) //left top
          }
        }
        this.drawLayer.entities.add(labelEntity)
      }


      // 添加点
      const addInfoPoint = (position) => {
        const labelEntity = new Entity()
        labelEntity.position = position
        labelEntity.point = {
          pixelSize: style?.point?.pixelSize || 10,
          outlineColor: style?.point?.outlineColor || Color.BLUE,
          outlineWidth: style?.point?.outlineWidth || 0,
          color: style?.point?.color || Color.WHITE
        }
        this.drawLayer.entities.add(labelEntity)
      }

      const create = () => {
        if (style?.line) {
          polygonEntity.polyline = {
            width: style?.line?.width || 3,
            material: style?.line?.material || Color.BLUE.withAlpha(0.8),
            clampToGround: clampToGround || false
          }
          polygonEntity.polyline.positions = new CallbackProperty(function () {
            return positions
          }, false)

        }
        polygonEntity.polygon = {
          hierarchy: new CallbackProperty(function () {
            return polygon
          }, false),

          material: style?.polygon?.material || Color.WHITE.withAlpha(0.1),
          clampToGround: options.clampToGround || false
        }
        polyObj = this.drawLayer.entities.add(polygonEntity)
      }

    }
  }

  /**
   * 画三角量测
   * @param options
   */
  drawTrianglesMeasureGraphics(options = {}) {
    const { style } = options
    let lineStyle = style.line || {
      width: 3,
      material: Color.BLUE.withAlpha(0.5)
    }
    if (window.viewer && options) {
      const _trianglesEntity = new Entity(),
          _tempLineEntity = new Entity(),
          _tempLineEntity2 = new Entity(),
          _positions = [],
          _tempPoints = [],
          _tempPoints2 = []
        const handler = new ScreenSpaceEventHandler(window.viewer.scene.canvas)
      // 高度
      function _getHeading(startPosition, endPosition) {
        if (!startPosition && !endPosition) return 0
        if (Cartesian3.equals(startPosition, endPosition)) return 0
        let cartographic = Cartographic.fromCartesian(startPosition)
        let cartographic2 = Cartographic.fromCartesian(endPosition)
        return (cartographic2.height - cartographic.height).toFixed(2)
      }
      // 偏移点
      function _computesHorizontalLine(positions) {
        let cartographic = Cartographic.fromCartesian(positions[0])
        let cartographic2 = Cartographic.fromCartesian(positions[1])
        return Cartesian3.fromDegrees(
            CesiumMath.toDegrees(cartographic.longitude),
            CesiumMath.toDegrees(cartographic.latitude),
            cartographic2.height
        )
      }
      // 鼠标左键点击
      handler.setInputAction((movement) => {
        const position = this.getCatesian3FromPX(movement.position)
        if (!position && !position.z) return false
        if (_positions.length === 0) {
          _positions.push(position.clone())
          _positions.push(position.clone())
          _tempPoints.push(position.clone())
          _tempPoints.push(position.clone())
        } else {
          handler.destroy()
          if (typeof options.callback === 'function') {
            options.callback({ e: _trianglesEntity, e2: _tempLineEntity, e3: _tempLineEntity2 })
          }
        }
      }, ScreenSpaceEventType.LEFT_CLICK)
      // 鼠标移动时候
      handler.setInputAction((movement) => {
        const position = this.getCatesian3FromPX(movement.endPosition)
        if (position && _positions.length > 0) {
          //直线
          _positions.pop()
          _positions.push(position.clone())
          let horizontalPosition = _computesHorizontalLine(_positions)
          //高度
          _tempPoints.pop()
          _tempPoints.push(horizontalPosition.clone())
          //水平线
          _tempPoints2.pop()
          _tempPoints2.pop()
          _tempPoints2.push(position.clone())
          _tempPoints2.push(horizontalPosition.clone())
        }
      }, ScreenSpaceEventType.MOUSE_MOVE)

      // 创建实例

      //直线
      _trianglesEntity.polyline = {
        positions: new CallbackProperty(function () {
          return _positions
        }, false),
        ...lineStyle
      }
      _trianglesEntity.position = new CallbackProperty(function () {
        return _positions[0]
      }, false)
      _trianglesEntity.point = {
        pixelSize: style?.point?.pixelSize || 5,
        outlineColor: style?.point?.outlineColor || Color.BLUE,
        outlineWidth: style?.point?.outlineWidth || 5
      }
      _trianglesEntity.label = {
        text: new CallbackProperty(() => {
          return '直线:' + this.getPositionDistance(this.transformCartesianArrayToWGS84Array(_positions)) + '米'
        }, false),
        show: true,
        showBackground: true,
        font: '14px monospace',
        horizontalOrigin: HorizontalOrigin.LEFT,
        verticalOrigin: VerticalOrigin.BOTTOM,
        pixelOffset: new Cartesian2(50, -100) //left top
      }
      //高度
      _tempLineEntity.polyline = {
        positions: new CallbackProperty(function () {
          return _tempPoints
        }, false),
        ...lineStyle
      }
      _tempLineEntity.position = new CallbackProperty(function () {
        return _tempPoints2[1]
      }, false)
      _tempLineEntity.point = {
        pixelSize: style?.point?.pixelSize || 5,
        outlineColor: style?.point?.outlineColor || Color.BLUE,
        outlineWidth: style?.point?.outlineWidth || 5
      }
      _tempLineEntity.label = {
        text: new CallbackProperty(function () {
          return '高度:' + _getHeading(_tempPoints[0], _tempPoints[1]) + '米'
        }, false),
        show: true,
        showBackground: true,
        font: '14px monospace',
        horizontalOrigin: HorizontalOrigin.LEFT,
        verticalOrigin: VerticalOrigin.BOTTOM,
        pixelOffset: new Cartesian2(-20, 100) //left top
      }
      //水平
      _tempLineEntity2.polyline = {
        positions: new CallbackProperty(function () {
          return _tempPoints2
        }, false),
        ...lineStyle
      }
      _tempLineEntity2.position = new CallbackProperty(function () {
        return _positions[1]
      }, false)

      _tempLineEntity2.point = {
        pixelSize: style?.point?.pixelSize || 5,
        outlineColor: style?.point?.outlineColor || Color.BLUE,
        outlineWidth: style?.point?.outlineWidth || 5
      }
      _tempLineEntity2.label = {
        text: new CallbackProperty( () =>{
          return (
              '水平距离:' + this.getPositionDistance(this.transformCartesianArrayToWGS84Array(_tempPoints2)) + '米'
          )
        }, false),
        show: true,
        showBackground: true,
        font: '14px monospace',
        horizontalOrigin: HorizontalOrigin.LEFT,
        verticalOrigin: VerticalOrigin.BOTTOM,
        pixelOffset: new Cartesian2(-150, -20) //left top
      }
      this.drawLayer.entities.add(_tempLineEntity2)
      this.drawLayer.entities.add(_tempLineEntity)
      this.drawLayer.entities.add(_trianglesEntity)
    }

  }


  /**
   * 传入两个点位返回矩形四个点的坐标
   * @param lTop
   * @param rBottom
   * @returns {[]}
   */
  computeRectanglePos(lTop, rBottom) {
    const positions = []
    const leftTop = this.transformCartesianToWGS84(lTop);
    const rightBottom = this.transformCartesianToWGS84(rBottom);
    const rightTop = {
      "lng": rightBottom.longitude,
      "lat": leftTop.latitude
    };
    const rightTop2 = Cartesian3.fromDegrees(rightTop.lng, rightTop.lat)
    // 计算左下角的坐标
    const leftBottom = {
      "lng": leftTop.longitude,
      "lat": rightBottom.latitude
    };
    const leftBottom2 = Cartesian3.fromDegrees(leftBottom.lng, leftBottom.lat)
    positions.push(rightTop2.clone(), rBottom.clone(), leftBottom2.clone(), lTop.clone())
    return positions
  }


  /**
   * 绘制矩形
   * @param options
   */
  drawRectangleMeasureGraphics(options = {}) {
    const { clampToGround, measure, style } = options
    if (window.viewer && options) {
      let positions = [],
          polyObj = null,
          rectangle = new PolygonHierarchy(),
          _polygonEntity = new Entity(),
          labelEntityOne,
          area = 0
         const handler  = new ScreenSpaceEventHandler(window.viewer.scene.canvas)
      // left
      handler.setInputAction((movement) => {
        const cartesian = this.getCatesian3FromPX(movement.position)
        addInfoPoint(cartesian)

        if (cartesian && cartesian.x) {
          if (positions.length === 0) {
            rectangle.positions.push(cartesian.clone())
            positions.push(cartesian.clone())

          } else {
            let otherPos = this.computeRectanglePos(positions[0], cartesian)
            console.log(otherPos, "");
            positions.push(...otherPos)
            if (positions.length > 1) {
              positions.splice(-4)
              rectangle.positions.splice(-4)
            }
            positions.map((pos) => {
              rectangle.positions.push(pos)
            })
            //清除鼠标事件
            if (handler) handler.destroy()
            //清除提示
            if (labelEntityOne) this.drawLayer.entities.remove(labelEntityOne)
            if (typeof options.callback === 'function') {
              options.callback({
                points: this.transformCartesianArrayToWGS84Array(positions),
                entity: polyObj,
                measure: Number(area)
              })
              // options.callback($this.transformCartesianArrayToWGS84Array(positions), polyObj)
            }
            //如果measure==true就计算面积
            if (measure === true) {
              if (style.centerPoint) {
                const center = this.computePolygonCenter(positions)
                if (center) _addInfoPoint(center)
              } else {
                _addInfoPoint(cartesian)
              }
            }
          }
          if (!polyObj) create()
        }

      }, ScreenSpaceEventType.LEFT_CLICK)
      handler.setInputAction((movement) => {
        const cartesian = this.getCatesian3FromPX(movement.endPosition)
        //鼠标提示信息
        if (labelEntityOne) this.drawLayer.entities.remove(labelEntityOne)
        const _labelEntityOne = new Entity()
        _labelEntityOne.position = cartesian
        _labelEntityOne.label = {
          text: '点击两个点后自动完成绘制',
          show: true,
          showBackground: true,
          font: '14px monospace',
          horizontalOrigin: HorizontalOrigin.LEFT,
          verticalOrigin: VerticalOrigin.BOTTOM,
          pixelOffset: new Cartesian2(-20, -80) //left top
        }
        labelEntityOne = this.drawLayer.entities.add(_labelEntityOne)
        if (positions.length > 1) {
          positions.splice(-4)
          rectangle.positions.splice(-4)
        }
        let otherPos = this.computeRectanglePos(positions[0], cartesian)
        positions.push(...otherPos)
        positions.map((pos) => {
          rectangle.positions.push(pos)
        })


      }, ScreenSpaceEventType.MOUSE_MOVE)

      const create = () => {
        _polygonEntity.polyline = {
          width: style?.line?.width || 3,
          material: style?.line?.material || Color.BLUE.withAlpha(0.8),
          clampToGround: clampToGround || false,
          show: !(JSON.stringify(style?.line?.show) === 'false')
        }

        _polygonEntity.polyline.positions = new CallbackProperty(() => {
          return positions
        }, false)



        _polygonEntity.polygon = {
          hierarchy: new CallbackProperty(() => {
            return rectangle
          }, false),

          material: style?.polygon?.material || Color.WHITE.withAlpha(0.1),
          clampToGround: clampToGround || false
        }

        polyObj = this.drawLayer.entities.add(_polygonEntity)
      }
      //鼠标打点
      const addInfoPoint = (position) => {
        const _labelEntity = new Entity()
        _labelEntity.position = position
        _labelEntity.point = {
          pixelSize: style?.point?.pixelSize || 10,
          outlineColor: style?.point?.outlineColor || Color.BLUE,
          outlineWidth: style?.point?.outlineWidth || 0,
          color: style?.point?.color || Color.WHEAT,
          show: JSON.stringify(style?.point?.show) !== 'false'

        }
        this.drawLayer.entities.add(_labelEntity)
      }
      //添加坐标点
      const _addInfoPoint = (position) => {
        const _labelEntity = new Entity()
        _labelEntity.position = position
        _labelEntity.point = {
          pixelSize: style?.centerPoint?.pixelSize || 10,
          outlineColor: style?.centerPoint?.outlineColor || Color.BLUE,
          outlineWidth: style?.centerPoint?.outlineWidth || 0,
          color: style?.centerPoint?.color || Color.WHEAT,
          show: JSON.stringify(style?.centerPoint?.show) !== 'false'
        }
        if (measure) {
          area = this.getPositionsArea(this.transformCartesianArrayToWGS84Array(positions))
          _labelEntity.label = {
            text:
                (area / 1000000.0).toFixed(4) +
                '平方公里',
            show: true,
            showBackground: true,
            font: '14px monospace',
            horizontalOrigin: HorizontalOrigin.LEFT,
            verticalOrigin: VerticalOrigin.BOTTOM,
            pixelOffset: new Cartesian2(-55, -10) //left top
          }
        }

        this.drawLayer.entities.add(_labelEntity)
      }
    }
  }


  /**
   * 绘制圆形
   * @param options
   */
  drawCircleMeasureGraphics(options = {}) {
    const { clampToGround, measure, style } = options
    if (window.viewer && options) {
      let positions = [],
          polyObj = null,
          _labelEntity,
          _polygonEntity = new Entity(),
          center,
          radius = 500,
          labelEntityOne
          const handler  = new ScreenSpaceEventHandler(window.viewer.scene.canvas)
      const create = () => {
        _polygonEntity.ellipse = {
          semiMinorAxis: new CallbackProperty(() => {

            // 在这个回调函数中动态计算圆形的半径
            return radius
          }, true),
          semiMajorAxis: new CallbackProperty(() => {
            // 在这个回调函数中动态计算圆形的半径
            return radius
          }, true),
          height: 0,//
          material: style?.circle?.material || Color.RED.withAlpha(0.5),
          outline: true, // 显示边框
          outlineColor: style?.circle?.outlineColor || Color.GREEN, // 边框颜色
          zIndex: 5,
          clampToGround: clampToGround || false
        }
        polyObj = this.drawLayer.entities.add(_polygonEntity)
      }
      if (!polyObj) {
        create()
      }
      handler.setInputAction((movement) => {
        const cartesian = this.getCatesian3FromPX(movement.position)

        if (cartesian && cartesian.x) {
          if (positions.length === 0) {
            _labelEntity = addInfoPoint(cartesian)
            _polygonEntity.position = new CallbackProperty( () => {
              // 在这个回调函数中动态计算圆形的位置（中心点）
              return cartesian;
            }, false);
            if (!center) center = cartesian

            positions.push(cartesian)
          } else {
            radius = Number(this.getPositionDistance(this.transformCartesianArrayToWGS84Array([center, cartesian])))
            //清除鼠标事件
            if (handler) handler.destroy()
            //清除提示
            if (labelEntityOne) this.drawLayer.entities.remove(labelEntityOne)
            if (typeof options.callback === 'function') {
              options.callback(
                  {
                    center: this.transformCartesianArrayToWGS84Array([center]),
                    radius: radius
                  }
                  , polyObj)
            }
          }
        }
      }, ScreenSpaceEventType.LEFT_CLICK)

      handler.setInputAction((movement) => {
        const cartesian = this.getCatesian3FromPX(movement.endPosition)

        //鼠标提示信息
        if (labelEntityOne) this.drawLayer.entities.remove(labelEntityOne)

        radius = Number(this.getPositionDistance(this.transformCartesianArrayToWGS84Array([center, cartesian])))
        // 计算圆形的面积

        if (measure) {
          if (!_labelEntity) {
            _labelEntity = addInfoPoint(center)
          }
          const circleArea = Math.PI * Math.pow(radius, 2);
          _labelEntity.label = {
            text:
                (circleArea / 1000000.0).toFixed(4) +
                '平方公里',

            show: true,
            showBackground: true,
            font: '14px monospace',
            horizontalOrigin: HorizontalOrigin.LEFT,
            verticalOrigin: VerticalOrigin.BOTTOM,
            pixelOffset: new Cartesian2(-55, -10) //left top
          }
        }
        const _labelEntityOne = new Entity()
        _labelEntityOne.position = cartesian
        _labelEntityOne.label = {
          text: positions.length > 0 ? '再次单机后结束绘制' : '单击打开始绘制',
          show: true,
          showBackground: true,
          font: '14px monospace',
          horizontalOrigin: HorizontalOrigin.LEFT,
          verticalOrigin: VerticalOrigin.BOTTOM,
          pixelOffset: new Cartesian2(-20, -80) //left top
        }
        labelEntityOne = this.drawLayer.entities.add(_labelEntityOne)

      }, ScreenSpaceEventType.MOUSE_MOVE)
      const addInfoPoint = (position) => {
        const _labelEntity = new Entity()
        _labelEntity.position = position

        _labelEntity.point = {
          pixelSize: style?.centerPoint?.pixelSize || 10,
          outlineColor: style?.centerPoint?.outlineColor || Color.BLUE,
          outlineWidth: style?.centerPoint?.outlineWidth || 0,
          color: style?.centerPoint?.color || Color.WHEAT,
          zIndex: 10,
          show: JSON.stringify(style?.centerPoint?.show) !== 'false'


        }
        // 获取原始位置
        const originalPosition = _labelEntity.position.getValue(JulianDate.now());
        // 向上偏移 100 米
        const newHeight = 10; // 向上偏移 100 米
        const newPosition = new Cartesian3(originalPosition.x, originalPosition.y, originalPosition.z + newHeight);
        // 更新 entity 的位置属性
        _labelEntity.position.setValue(newPosition);
        this.drawLayer.entities.add(_labelEntity)
        return _labelEntity
      }
    }
  }

  /**
   * 清除所有的实例
   */
  removeAll() {
    this.drawLayer.removeAll()
  }

}